
struct Parser<'g> {
    input: &'g str,
}

#[derive(Debug,PartialEq)]
enum ParserError {
    ArgumentInvalid,
    NotFound,
    FormatInvalid,
    ValueEmpty,
    //NotSupport,
}

impl <'g> Parser <'g> {
    fn from_str(input: &'g str) -> Self {
        Parser { input }
    }

    // found -> : Ok(string) =>  { 
    //          string: |non-empty|-> Ok(string);
    //          object, |non-empty|-> Ok(string);
    //          array,  |non-empty|-> Ok(string);
    // };
    // ArgumentInvalid -> Err(ArgumentInvalid)
    // not-found -> : Err(NotFound) 
    // format invalid -> Err(FormatInvalid)
    // ValueEmpty  -> Err(ValueEmpty)
    fn find(&mut self, key: &str) -> Result<&'g str, ParserError> {
        loop {
            let k = self.key()?;        
            if self.separator('=').is_err() {
                return Err(ParserError::FormatInvalid);
            }
            if k == key { //found 
                let v = self.fast_value(key)?;
                return  if v.len() > 0 { 
                            Ok(v)
                        } else { 
                            Err(ParserError::ValueEmpty) 
                        };
            }

            //TODO: ???????? [string, object, array => string -> consume; object|array -> find continue
            if let Err(e) = self.value(key) {
                if e == ParserError::NotFound  {
                    if self.input.len() == 0 {
                        return Err(e)
                    }
                    //else self.input.len() > 0 => continue find
                }
                else {
                    return Err(e)
                }
            }
            if self.separator(',').is_err() {
                return Err(ParserError::FormatInvalid);
            }
        }
    }
    fn object(&mut self, key: &str) -> Result<&'g str, ParserError> {
        if self.separator('{').is_err() {
            return Err(ParserError::FormatInvalid);
        }
        let val = self.find(key)?;
        if self.separator('}').is_err() {
            return Err(ParserError::FormatInvalid);
        }
        return Ok(val);
    }
    fn value(&mut self, key: &str) -> Result<&'g str, ParserError> {
        match self.peek_char() {
            Some(ch) => {
                match ch {
                    '{' => {
                        return self.object(key);
                    },
                    '[' => {
                        self.input = &self.input[1..];
                        return Err(ParserError::ArgumentInvalid);
                        //TODO: 
                    },
                    _ => {
                        return self.string();
                    }
                }
            },
            None => {
                return Err(ParserError::FormatInvalid);
            }
        }
    }
    fn fast_value(&mut self, key: &str) -> Result<&'g str, ParserError> {
        //TODO:
        self.value(key)
    }
    fn string(&mut self) -> Result<&'g str, ParserError> {
        let start = self.input;
        let mut count = 0usize;
        loop {
            match self.peek_char() {
                Some(ch) => {
                    match ch {
                        ',' | ']' | '}' => {
                            // maybe formate Error for [X01=hello,]
                            if count == 0 {
                                return Err(ParserError::ValueEmpty);
                            }
                            break; // exit the loop if meet the end char in string
                        }
                        _ => {
                            count += 1;
                            self.input = &self.input[1..];
                        }
                    }
                }//Some(ch)
                None => {
                     //exit the loop if end of string
                     if count == 0 {
                         return Err(ParserError::FormatInvalid);
                     }
                     break;
                }
            }
        } //loop

        Ok(&start[0..count])
    }

    fn peek_char(&self) -> Option<char>{
        self.input.chars().next()
    }
    fn next_char(&mut self)-> Option<char>{
        let ch = self.peek_char()?;
        self.input = &self.input[ch.len_utf8()..];
        Some(ch)
    }

    // len = 0 => FormatInvalid
    // len >= 1 => ch == '=' => Ok(ch)
    //          => ch != '=' =>  FormatInvalid
    fn separator(&mut self, ch: char) -> Result<bool, ParserError> {
        if let Some(c) = self.next_char() {
            return Ok(c == ch );
        }
        Err(ParserError::FormatInvalid)
    }
    fn key(&mut self) -> Result<&'g str, ParserError> {
        if self.input.len() >= 3 {
            let ret = &self.input[0..3];
            self.input = &self.input[3..];
            return Ok(ret);
        }
        Err(ParserError::ArgumentInvalid)
    }
}


#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test(){
        fn __test(gtp: &str, tag: &str, expect: Result<&str, ParserError>) {
            let mut p = Parser::from_str(gtp);
            assert_eq!(expect, p.find(tag));
        }

        //let gtp = "X01=hello"; key=X01; Ok("hello")
        __test("X01=hello", "X01",  Ok("hello"));
        __test("X01=hello,X02=world", "X02",  Ok("world"));
        __test("X01=hello,X02=world,X03=hhh,X04=xxx,X05=xdd", "X05",  Ok("xdd"));
        __test("", "X01", Err(ParserError::ArgumentInvalid));
        //__test("X01=hello", "X02", Err(ParserError::NotFound));
        __test("X01", "X01", Err(ParserError::FormatInvalid));
        __test("X01=", "X01", Err(ParserError::FormatInvalid));
        __test("X01=,X02=34", "X01", Err(ParserError::ValueEmpty));

        __test("X01=hello,", "X01",  Ok("hello")); 
        /*
        */

        // object let gtp = "X01={X02=hello}"; key X01; Ok({X02=hello})
        //TODO: __test("X01={X02=hello}", "X02", Ok("hello"));

        /* TODO:
        //array let gtp = "X01=[hello0,hello1]"; key"X01"   Ok([hello0,hello1])
        __test("X01=[hello0,hello1]", "X01", Ok("[hello0,hello1]"));
        */
        /*
        // TODO:  exception case ????
        __test("X01=hello]", "X01",  Err(ParserError::FormatInvalid));
        __test("X01=hello}", "X01",  Err(ParserError::FormatInvalid));
        */
    }
}
